package com.ruoyi.brand;

import cn.hutool.core.util.IdUtil;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvasConstants;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.Div;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Text;
import com.itextpdf.layout.properties.FloatPropertyValue;
import com.itextpdf.layout.properties.Property;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.UnitValue;
import com.ruoyi.base.domain.vo.LotteryItemVo;
import com.ruoyi.base.domain.vo.LotteryVo;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.config.PDFConstants;
import com.ruoyi.sale.domain.SaleConfigStyle;
import com.ruoyi.utils.LotteryUtil;
import com.ruoyi.utils.PropertiesDailyGenerator;
import com.ruoyi.utils.FontsUtil;
import com.ruoyi.utils.QRCodeGeneratorUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Component
public class ShanXian3DdanShi {

    private static String uploadPath = PDFConstants.uploadPath;
    private static SimpleDateFormat sdfymd = new SimpleDateFormat("yyyyMMdd");

    // 缓存字体数据，避免重复加载
    private static Map<String, byte[]> fontCache = new HashMap<>();
    private static Map<String, byte[]> imageCache = new HashMap<>();

    public static Map<String,String> generateLotteryTicket(LotteryVo lotter, SaleConfigStyle configStyle) {
        Map<String,String> map = new HashMap<>();
        map.put("money","0");
        map.put("path","");
        map.put("status","yes");
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
            SimpleDateFormat sdfYear = new SimpleDateFormat("yy-MM-dd");
            SimpleDateFormat years = new SimpleDateFormat("yyyy");

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

            String outPath = uploadPath + File.separator + sdfymd.format(new Date()) + File.separator;
            File folder = new File(outPath);

            // 文件夹不存在，创建文件夹（包括父目录）
            if (!folder.exists()) {
                folder.mkdirs();
            }

            String fileOutPath = outPath + IdUtil.getSnowflakeNextId() + ".pdf";
            File outFile = new File(fileOutPath);
            if (!outFile.exists()) {
                System.out.println(outFile.getPath());
                outFile.createNewFile();
            }

            PageSize pageSize = new PageSize(mmToPoints(80), mmToPoints(105));

            // 创建PDF文档
            PdfWriter writer = new PdfWriter(outputStream);
            PdfDocument pdf = new PdfDocument(writer);
            Document document = new Document(pdf, pageSize); // 使用小尺寸页面

            float topMargin = mmToPoints(13);    // 上下边距
            float bottomMargin = mmToPoints(0);    // 上下边距
            float leftMargin = mmToPoints(1); // 左右边距
            float rightMargin = mmToPoints(1); // 左右边距
            document.setMargins(topMargin, rightMargin, bottomMargin, leftMargin);

            float leftbj = 5;

            // 设置中文字体（需要确保系统有中文字体）
            PdfFont font = PdfFontFactory.createFont();
            document.setFont(font);

            List<LotteryItemVo> itemList = lotter.getItemList();
            int mone = 0;
            for (LotteryItemVo item : itemList) {
                mone += item.getItemMult().intValue() * 2;
            }

            String qishu = years.format(new Date()) + PropertiesDailyGenerator.getDailyStage();

            String money = String.valueOf(mone);
            String code = LotteryUtil.generateStrNum();
            String kjq = qishu + " " + sdfYear.format(new Date());
            String xsq = qishu + "-" + PropertiesDailyGenerator.getDailySort();
            String xssj = sdf.format(new Date());
            String jh = "61012344";
            if (StringUtils.isNotEmpty(configStyle.getSpacJih())){
                jh = configStyle.getSpacJih();
            }

            double result = mone * 0.34;
            String formattedResult = String.format("%.2f", result);
            String gongyi = "感谢您为公益事业贡献" + formattedResult + "元";

            PdfFont hb1 = FontsUtil.getFonts_IDENTITY_H("static/fonts/hb1.otf");
            PdfFont ACAIPIAOZITI_H = FontsUtil.getFonts_IDENTITY_H("static/fonts/ACAIPIAOZITI11.TTF");
            PdfFont STYSZ = FontsUtil.getFonts_IDENTITY_H("static/fonts/宋体与数字结合.ttf");

            SolidBorder border = new SolidBorder(0.1f);
            Div mainDiv = new Div()
                    .setMarginLeft(1)
                    .setMarginRight(1)
                    .setHeight(mmToPoints(90))
                    .setWidth(mmToPoints(78))
                    .setPadding(0);
            Text btbd = new Text(":");
            btbd.setFontSize(3);
            btbd.setFont(ACAIPIAOZITI_H);
            btbd.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.INVISIBLE);

            Text btbd1 = new Text(":");
            btbd1.setFontSize(11);
            btbd1.setFont(ACAIPIAOZITI_H);


            Text btbd2 = new Text(":");
            btbd2.setFontSize(3);
            btbd2.setFont(ACAIPIAOZITI_H);
            btbd2.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.INVISIBLE);

            Text bt1 = new Text("玩法")
                    .setFont(ACAIPIAOZITI_H)
                    .setFontSize(11.5F)
                    .setTextAlignment(TextAlignment.LEFT)
                    .setCharacterSpacing(-0.5f);

            Text bt2 = new Text("              机号")
                    .setFont(ACAIPIAOZITI_H)
                    .setFontSize(11.5F)
                    .setTextAlignment(TextAlignment.LEFT)
                    .setCharacterSpacing(-0.5f);

            Text bt3 = new Text(jh)
                    .setFont(ACAIPIAOZITI_H)
                    .setFontSize(11.5F)
                    .setTextAlignment(TextAlignment.LEFT)
                    .setCharacterSpacing(0.6f);

            // 添加标题
            Paragraph title = new Paragraph()
                    .setFont(ACAIPIAOZITI_H)
                    .setFontSize(11.5F)
                    .setMarginBottom(3f)
                    .setMarginLeft(4)
                    .add(bt1).add(btbd).add(btbd1).add(btbd2)
                    .add("3D-单式")
                    .add(bt2).add(btbd).add(btbd1).add(btbd2).add(bt3);
            mainDiv.add(title);
            //document.add(title);

            // 添加代码信息
            Paragraph pcode = new Paragraph(code)
                    .setMarginTop(-8f)
                    .setFont(ACAIPIAOZITI_H)
                    .setFontSize(11F)
                    .setMarginLeft(leftbj)
                    .setCharacterSpacing(-0.29f)
                    .setTextAlignment(TextAlignment.JUSTIFIED)
                    .setWidth(mmToPoints(69));
            mainDiv.add(pcode);
            //document.add(mainDiv);


            Text textbd = new Text(": ");
            textbd.setFontSize(15f);
            textbd.setFont(hb1);
            textbd.setBold();

            Div div = new Div();
            // 设置固定高度
            div.setHeight(mmToPoints(26));
            div.setWidth(mmToPoints(70));
            div.setMarginTop(-6);
            div.setMarginLeft(3.9f);
//            div.setBorder(border);

            for (int i = 0; i < itemList.size(); i++) {
                LotteryItemVo item = itemList.get(i);
                Text moshi = new Text(item.getItemType());
                moshi.setFontSize(10.5f);
                moshi.setFont(STYSZ);
                //moshi.setBold();
                //moshi.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.FILL_STROKE);
                //moshi.setStrokeWidth(0.05f);

                String itemVal = item.getItemVal();
                Text zhuma = new Text(itemVal);
                zhuma.setFontSize(17f);
                zhuma.setFont(STYSZ);
                zhuma.setCharacterSpacing(12.5F);
                zhuma.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.FILL_CLIP);
                zhuma.setStrokeWidth(1f);

                int itemMult = item.getItemMult().intValue();
                Text mult = new Text(itemMult + "");
                mult.setFontSize(17f);
                mult.setFont(STYSZ);
                mult.setTextRise(1);


                Text leftkh = new Text("      (");
                leftkh.setFontSize(17f);
                leftkh.setFont(ACAIPIAOZITI_H);
                leftkh.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.FILL_STROKE);
                leftkh.setStrokeWidth(0.5f);

                Text leftkh2 = new Text("       (");
                leftkh2.setFontSize(17f);
                leftkh2.setFont(ACAIPIAOZITI_H);
                leftkh2.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.FILL_STROKE);
                leftkh2.setStrokeWidth(0.5f);

                Text rightkh = new Text(")");
                rightkh.setFontSize(17f);
                rightkh.setFont(ACAIPIAOZITI_H);
                rightkh.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.FILL_STROKE);
                rightkh.setStrokeWidth(0.5f);

                if (itemMult>9){
                    mult.setCharacterSpacing(-1.35f);
                    leftkh2.setCharacterSpacing(-1.35f);
                    rightkh.setCharacterSpacing(-1.35f);
                }

                // 添加组三复式投注信息
                Paragraph betType = new Paragraph();
                betType.setMarginLeft(6.5f);
                betType.setMarginTop(-17.5f);
                betType.add(moshi);
                betType.add(textbd);
                betType.add(zhuma);
                if(itemMult>9){
                    betType.add(leftkh2).add(mult).add(rightkh);
                }else{
                    betType.add(leftkh).add(mult).add(rightkh);
                }
                div.add(betType);
            }
            div.setMarginTop(4);
            mainDiv.add(div);

            Text textbd2 = new Text(":");
            textbd2.setFontSize(9f);
            textbd2.setFont(hb1);

            Text yuan = new Text("元");
            yuan.setFontSize(11f);
            yuan.setFont(STYSZ);

            Text heji = new Text("合计");
            heji.setFontSize(11f);
            heji.setFont(STYSZ);

            Text texthj = new Text(money);
            texthj.setFontSize(16.7f);
            texthj.setFont(STYSZ);

            Div mainKj = new Div();
            mainKj.setHeight(mmToPoints(7));
            mainKj.setMarginTop(-9);

            Div leftKj = new Div();
            leftKj.setWidth(mmToPoints(48));
            leftKj.setProperty(Property.FLOAT, FloatPropertyValue.LEFT);
//            leftKj.setBorder(border);

            Text textkjq = new Text("开奖期");
            textkjq.setFontSize(12);
            textkjq.setCharacterSpacing(-0.8f);

            Paragraph kaijiang = new Paragraph()
                    .setFont(ACAIPIAOZITI_H)
                    .setMarginTop(-1f)
                    .setMarginLeft(3.5F)
                    .add(textkjq)
                    .add(textbd2).add(kjq)
                    .setFontSize(11.5f)
                    .setTextAlignment(TextAlignment.LEFT);

            leftKj.add(kaijiang);

            Div rightKj = new Div();
            rightKj.setWidth(mmToPoints(21f));
            rightKj.setProperty(Property.FLOAT, FloatPropertyValue.RIGHT);
            rightKj.setMarginRight(18);
//            rightKj.setBorder(border);

            Paragraph kjrq = new Paragraph()
                    .setMarginTop(-9.5f)
                    .add(heji)
                    .add(texthj)
                    .add(yuan)
                    .setTextAlignment(TextAlignment.RIGHT)
                    .setCharacterSpacing(-1.5f);
            rightKj.add(kjrq);
            mainKj.add(leftKj);
            mainKj.add(rightKj);
            mainDiv.add(mainKj);

            Div mainXS = new Div();
            mainXS.setHeight(mmToPoints(7));
            mainXS.setMarginTop(-6);

            Div leftXS = new Div();
            leftXS.setWidth(mmToPoints(38));
            leftXS.setProperty(Property.FLOAT, FloatPropertyValue.LEFT);
//            leftXS.setBorder(border);

            Text textxsq = new Text("销售期");
            textxsq.setFontSize(12);
            textxsq.setCharacterSpacing(-0.8f);

            Paragraph xiaoshou = new Paragraph()
                    .setMarginTop(-1f)
                    .setMarginLeft(3f)
                    .setFont(ACAIPIAOZITI_H)
                    .add(textxsq)
                    .add(textbd2).add(xsq)
                    .setFontSize(11.5f)
                    .setTextAlignment(TextAlignment.LEFT);
            leftXS.add(xiaoshou);

            Div rightXS = new Div();
            rightXS.setWidth(mmToPoints(34f));
            rightXS.setProperty(Property.FLOAT, FloatPropertyValue.RIGHT);
            rightXS.setMarginRight(3);
//            rightXS.setBorder(border);
            Paragraph xiaosRQ = new Paragraph(xssj)
                    .setMarginTop(-1f)
                    //.setMarginRight(2.5f)
                    .setCharacterSpacing(0.5f)
                    .setFont(ACAIPIAOZITI_H)
                    .setFontSize(11.5f)
                    .setTextAlignment(TextAlignment.RIGHT);
            rightXS.add(xiaosRQ);

            mainXS.add(leftXS);
            mainXS.add(rightXS);
            mainDiv.add(mainXS);

            Div mainQR = new Div();
            mainQR.setWidth(UnitValue.createPercentValue(100)); // 100% 宽度
            mainQR.setHeight(mmToPoints(18));
            mainQR.setMarginTop(-1);

            Div leftDiv = new Div();
            leftDiv.setWidth(UnitValue.createPercentValue(69f)); // 左边占65%
            leftDiv.setProperty(Property.FLOAT, FloatPropertyValue.LEFT);
            leftDiv.setHeight(mmToPoints(18));
            leftDiv.setMarginLeft(3);
            // 添加地址信息
            String address = "西安市灞桥区万科澜岸13\n-2-103";
            float spac = -0.7f;
            if (StringUtils.isNotEmpty(configStyle.getAddress())){
                address = configStyle.getAddress().replace("#","\n");
                spac = configStyle.getSpacStyle().floatValue();
            }
            Paragraph paddress = new Paragraph("地址")
                    .setMarginTop(-4.5f)
//                    .setMarginLeft(3)
                    .setFont(ACAIPIAOZITI_H)
                    .setFontSize(12)
                    .add(textbd2).add(address)
                    .setMultipliedLeading(1.1f)
                    .setTextAlignment(TextAlignment.LEFT)
                    .setCharacterSpacing(spac);
            //document.add(paddress);
            leftDiv.add(paddress);

            // 添加公益信息

            Paragraph donation = new Paragraph(gongyi);
            donation.setMarginTop(-6);
            donation.setFont(ACAIPIAOZITI_H);
            donation.setFontSize(11.6f);
            donation.setTextAlignment(TextAlignment.LEFT);
            donation.setCharacterSpacing(0);
            if (!gongyi.contains("1") && Double.valueOf(formattedResult) > 100){
                donation.setCharacterSpacing(-0.1f);
            }

            leftDiv.add(donation);

            Div rightDiv = new Div();
            rightDiv.setWidth(UnitValue.createPercentValue(29)); // 右边占30%
            rightDiv.setHeight(mmToPoints(20));
            rightDiv.setProperty(Property.FLOAT, FloatPropertyValue.RIGHT);
            rightDiv.setMarginTop(-2);
//            rightDiv.setBorder(border);

            String QRcontent = SecurityUtils.encryptPassword(IdUtils.fastSimpleUUID())+SecurityUtils.encryptPassword(IdUtils.fastSimpleUUID());

            QRCodeGeneratorUtil.QRCodeConfig qrCodeConfig = new QRCodeGeneratorUtil.QRCodeConfig(QRcontent);
            byte[] QRimageDataBytes = QRCodeGeneratorUtil.generateQRCodeToByte(qrCodeConfig);

            ImageData QRImageData = ImageDataFactory.create(QRimageDataBytes);
            Image QRImage = new Image(QRImageData);
            QRImage.setWidth(mmToPoints(25));  // 91mm宽度
            QRImage.setHeight(mmToPoints(25)); // 22.5mm高度
            QRImage.setMarginLeft(4);
            QRImage.setMarginTop(-7);
            QRImage.setBold();
            QRImage.setAutoScale(true);
            Paragraph QRimage = new Paragraph();
            QRimage.add(QRImage);
            rightDiv.add(QRimage);

            mainQR.add(leftDiv);
            mainQR.add(rightDiv);
            mainDiv.add(mainQR);

            Div divImage = new Div();
            divImage.setWidth(mmToPoints(105)); // 100% 宽度leftDiv
            divImage.setHeight(mmToPoints(22));
            divImage.setMarginTop(5);
            divImage.setPadding(0);
            divImage.setMarginRight(0);
//            divImage.setBorder(border);

            byte[] imageDataBytes = FontsUtil.readImageAsBytes("images/" + LotteryUtil.getImageNum() + ".jpg");

            //byte[] imageDataBytes = loadImageData("static/images/" + LotteryUtil.getImageNum() + ".png");
            if (imageDataBytes != null) {
                ImageData imageData = ImageDataFactory.create(imageDataBytes);
                Image image = new Image(imageData);

                // 设置图片大小
                //image.setWidth(mmToPoints(90));  // 91mm宽度
                //image.setHeight(mmToPoints(18)); // 22.5mm高度
                image.setMarginTop(3);
                image.setMarginLeft(2);

//                image.setBold();
                image.setAutoScale(true);

                // 创建段落并添加图片
                Paragraph pimage = new Paragraph();
                pimage.add(image);
                divImage.add(pimage);
                mainDiv.add(divImage);
                //document.add(divImage);
            } else {
                log.info("图片文件加载失败: static/images/1.png");
            }
            document.add(mainDiv);
            document.close();

            byte[] pdfBytes = outputStream.toByteArray();
            FileOutputStream fos = new FileOutputStream(fileOutPath);
            fos.write(pdfBytes);
            fos.flush();
            fos.close();

            map.put("money",money);
            map.put("path",fileOutPath);
            return map;
        } catch (Exception e) {
            log.info(e.getMessage());
            e.printStackTrace();
            map.put("status","no");
        }
        return map;
    }

    public static Text getTextVal(String val, PdfFont font) {
        Text text = new Text(val);
        text.setFontSize(15f);
        text.setFont(font);
        //text.setBold();
        text.setTextRenderingMode(PdfCanvasConstants.TextRenderingMode.FILL_STROKE);
        text.setStrokeWidth(0.2f);
        return text;
    }

    /**
     * 毫米转点
     */
    private static float mmToPoints(float mm) {
        return mm * 2.83465f;
    }

    /**
     * 像素转换为点
     */
    private float pixelsToPoints(float pixels) {
        return pixels * 0.75f;
    }


    /**
     * 从 classpath 加载图片数据
     */
    private static byte[] loadImageData(String imagePath) {
        return imageCache.computeIfAbsent(imagePath, path -> {
            try {
                ClassPathResource resource = new ClassPathResource(path);
                String paths = resource.getPath();
                if (!resource.exists()) {
                    log.error("图片文件不存在: {}", path);
                    return null;
                }
                try (InputStream inputStream = resource.getInputStream()) {
                    byte[] imageData = org.apache.commons.io.IOUtils.toByteArray(inputStream);
                    log.info("成功加载图片文件: {}, 大小: {} bytes", path, imageData.length);
                    return imageData;
                }
            } catch (Exception e) {
                log.error("加载图片文件失败: {}", path, e);
                return null;
            }
        });
    }

    public static void main(String[] args) {
        //generateLotteryTicket();
    }
}
